home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / DB / msql.php < prev    next >
Encoding:
PHP Script  |  2005-07-07  |  23.4 KB  |  811 lines

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  4.  
  5. /**
  6.  * The PEAR DB driver for PHP's msql extension
  7.  * for interacting with Mini SQL databases
  8.  *
  9.  * PHP's mSQL extension did weird things with NULL values prior to PHP
  10.  * 4.3.11 and 5.0.4.  Make sure your version of PHP meets or exceeds
  11.  * those versions.
  12.  *
  13.  * PHP versions 4 and 5
  14.  *
  15.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  16.  * that is available through the world-wide-web at the following URI:
  17.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  18.  * the PHP License and are unable to obtain it through the web, please
  19.  * send a note to license@php.net so we can mail you a copy immediately.
  20.  *
  21.  * @category   Database
  22.  * @package    DB
  23.  * @author     Daniel Convissor <danielc@php.net>
  24.  * @copyright  1997-2005 The PHP Group
  25.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  26.  * @version    CVS: $Id: msql.php,v 1.57 2005/02/22 07:26:46 danielc Exp $
  27.  * @link       http://pear.php.net/package/DB
  28.  */
  29.  
  30. /**
  31.  * Obtain the DB_common class so it can be extended from
  32.  */
  33. require_once 'DB/common.php';
  34.  
  35. /**
  36.  * The methods PEAR DB uses to interact with PHP's msql extension
  37.  * for interacting with Mini SQL databases
  38.  *
  39.  * These methods overload the ones declared in DB_common.
  40.  *
  41.  * PHP's mSQL extension did weird things with NULL values prior to PHP
  42.  * 4.3.11 and 5.0.4.  Make sure your version of PHP meets or exceeds
  43.  * those versions.
  44.  *
  45.  * @category   Database
  46.  * @package    DB
  47.  * @author     Daniel Convissor <danielc@php.net>
  48.  * @copyright  1997-2005 The PHP Group
  49.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  50.  * @version    Release: 1.7.6
  51.  * @link       http://pear.php.net/package/DB
  52.  * @since      Class not functional until Release 1.7.0
  53.  */
  54. class DB_msql extends DB_common
  55. {
  56.     // {{{ properties
  57.  
  58.     /**
  59.      * The DB driver type (mysql, oci8, odbc, etc.)
  60.      * @var string
  61.      */
  62.     var $phptype = 'msql';
  63.  
  64.     /**
  65.      * The database syntax variant to be used (db2, access, etc.), if any
  66.      * @var string
  67.      */
  68.     var $dbsyntax = 'msql';
  69.  
  70.     /**
  71.      * The capabilities of this DB implementation
  72.      *
  73.      * The 'new_link' element contains the PHP version that first provided
  74.      * new_link support for this DBMS.  Contains false if it's unsupported.
  75.      *
  76.      * Meaning of the 'limit' element:
  77.      *   + 'emulate' = emulate with fetch row by number
  78.      *   + 'alter'   = alter the query
  79.      *   + false     = skip rows
  80.      *
  81.      * @var array
  82.      */
  83.     var $features = array(
  84.         'limit'         => 'emulate',
  85.         'new_link'      => false,
  86.         'numrows'       => true,
  87.         'pconnect'      => true,
  88.         'prepare'       => false,
  89.         'ssl'           => false,
  90.         'transactions'  => false,
  91.     );
  92.  
  93.     /**
  94.      * A mapping of native error codes to DB error codes
  95.      * @var array
  96.      */
  97.     var $errorcode_map = array(
  98.     );
  99.  
  100.     /**
  101.      * The raw database connection created by PHP
  102.      * @var resource
  103.      */
  104.     var $connection;
  105.  
  106.     /**
  107.      * The DSN information for connecting to a database
  108.      * @var array
  109.      */
  110.     var $dsn = array();
  111.  
  112.  
  113.     /**
  114.      * The query result resource created by PHP
  115.      *
  116.      * Used to make affectedRows() work.  Only contains the result for
  117.      * data manipulation queries.  Contains false for other queries.
  118.      *
  119.      * @var resource
  120.      * @access private
  121.      */
  122.     var $_result;
  123.  
  124.  
  125.     // }}}
  126.     // {{{ constructor
  127.  
  128.     /**
  129.      * This constructor calls <kbd>$this->DB_common()</kbd>
  130.      *
  131.      * @return void
  132.      */
  133.     function DB_msql()
  134.     {
  135.         $this->DB_common();
  136.     }
  137.  
  138.     // }}}
  139.     // {{{ connect()
  140.  
  141.     /**
  142.      * Connect to the database server, log in and open the database
  143.      *
  144.      * Don't call this method directly.  Use DB::connect() instead.
  145.      *
  146.      * Example of how to connect:
  147.      * <code>
  148.      * require_once 'DB.php';
  149.      * 
  150.      * // $dsn = 'msql://hostname/dbname';  // use a TCP connection
  151.      * $dsn = 'msql:///dbname';             // use a socket
  152.      * $options = array(
  153.      *     'portability' => DB_PORTABILITY_ALL,
  154.      * );
  155.      * 
  156.      * $db =& DB::connect($dsn, $options);
  157.      * if (PEAR::isError($db)) {
  158.      *     die($db->getMessage());
  159.      * }
  160.      * </code>
  161.      *
  162.      * @param array $dsn         the data source name
  163.      * @param bool  $persistent  should the connection be persistent?
  164.      *
  165.      * @return int  DB_OK on success. A DB_Error object on failure.
  166.      */
  167.     function connect($dsn, $persistent = false)
  168.     {
  169.         if (!PEAR::loadExtension('msql')) {
  170.             return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
  171.         }
  172.  
  173.         $this->dsn = $dsn;
  174.         if ($dsn['dbsyntax']) {
  175.             $this->dbsyntax = $dsn['dbsyntax'];
  176.         }
  177.  
  178.         $params = array();
  179.         if ($dsn['hostspec']) {
  180.             $params[] = $dsn['port']
  181.                         ? $dsn['hostspec'] . ',' . $dsn['port']
  182.                         : $dsn['hostspec'];
  183.         }
  184.  
  185.         $connect_function = $persistent ? 'msql_pconnect' : 'msql_connect';
  186.  
  187.         $ini = ini_get('track_errors');
  188.         $php_errormsg = '';
  189.         if ($ini) {
  190.             $this->connection = @call_user_func_array($connect_function,
  191.                                                       $params);
  192.         } else {
  193.             ini_set('track_errors', 1);
  194.             $this->connection = @call_user_func_array($connect_function,
  195.                                                       $params);
  196.             ini_set('track_errors', $ini);
  197.         }
  198.  
  199.         if (!$this->connection) {
  200.             if (($err = @msql_error()) != '') {
  201.                 return $this->raiseError(DB_ERROR_CONNECT_FAILED,
  202.                                          null, null, null,
  203.                                          $err);
  204.             } else {
  205.                 return $this->raiseError(DB_ERROR_CONNECT_FAILED,
  206.                                          null, null, null,
  207.                                          $php_errormsg);
  208.             }
  209.         }
  210.  
  211.         if (!@msql_select_db($dsn['database'], $this->connection)) {
  212.             return $this->msqlRaiseError();
  213.         }
  214.         return DB_OK;
  215.     }
  216.  
  217.     // }}}
  218.     // {{{ disconnect()
  219.  
  220.     /**
  221.      * Disconnects from the database server
  222.      *
  223.      * @return bool  TRUE on success, FALSE on failure
  224.      */
  225.     function disconnect()
  226.     {
  227.         $ret = @msql_close($this->connection);
  228.         $this->connection = null;
  229.         return $ret;
  230.     }
  231.  
  232.     // }}}
  233.     // {{{ simpleQuery()
  234.  
  235.     /**
  236.      * Sends a query to the database server
  237.      *
  238.      * @param string  the SQL query string
  239.      *
  240.      * @return mixed  + a PHP result resrouce for successful SELECT queries
  241.      *                + the DB_OK constant for other successful queries
  242.      *                + a DB_Error object on failure
  243.      */
  244.     function simpleQuery($query)
  245.     {
  246.         $this->last_query = $query;
  247.         $query = $this->modifyQuery($query);
  248.         $result = @msql_query($query, $this->connection);
  249.         if (!$result) {
  250.             return $this->msqlRaiseError();
  251.         }
  252.         // Determine which queries that should return data, and which
  253.         // should return an error code only.
  254.         if (DB::isManip($query)) {
  255.             $this->_result = $result;
  256.             return DB_OK;
  257.         } else {
  258.             $this->_result = false;
  259.             return $result;
  260.         }
  261.     }
  262.  
  263.  
  264.     // }}}
  265.     // {{{ nextResult()
  266.  
  267.     /**
  268.      * Move the internal msql result pointer to the next available result
  269.      *
  270.      * @param a valid fbsql result resource
  271.      *
  272.      * @access public
  273.      *
  274.      * @return true if a result is available otherwise return false
  275.      */
  276.     function nextResult($result)
  277.     {
  278.         return false;
  279.     }
  280.  
  281.     // }}}
  282.     // {{{ fetchInto()
  283.  
  284.     /**
  285.      * Places a row from the result set into the given array
  286.      *
  287.      * Formating of the array and the data therein are configurable.
  288.      * See DB_result::fetchInto() for more information.
  289.      *
  290.      * This method is not meant to be called directly.  Use
  291.      * DB_result::fetchInto() instead.  It can't be declared "protected"
  292.      * because DB_result is a separate object.
  293.      *
  294.      * PHP's mSQL extension did weird things with NULL values prior to PHP
  295.      * 4.3.11 and 5.0.4.  Make sure your version of PHP meets or exceeds
  296.      * those versions.
  297.      *
  298.      * @param resource $result    the query result resource
  299.      * @param array    $arr       the referenced array to put the data in
  300.      * @param int      $fetchmode how the resulting array should be indexed
  301.      * @param int      $rownum    the row number to fetch (0 = first row)
  302.      *
  303.      * @return mixed  DB_OK on success, NULL when the end of a result set is
  304.      *                 reached or on failure
  305.      *
  306.      * @see DB_result::fetchInto()
  307.      */
  308.     function fetchInto($result, &$arr, $fetchmode, $rownum = null)
  309.     {
  310.         if ($rownum !== null) {
  311.             if (!@msql_data_seek($result, $rownum)) {
  312.                 return null;
  313.             }
  314.         }
  315.         if ($fetchmode & DB_FETCHMODE_ASSOC) {
  316.             $arr = @msql_fetch_array($result, MSQL_ASSOC);
  317.             if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
  318.                 $arr = array_change_key_case($arr, CASE_LOWER);
  319.             }
  320.         } else {
  321.             $arr = @msql_fetch_row($result);
  322.         }
  323.         if (!$arr) {
  324.             return null;
  325.         }
  326.         if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
  327.             $this->_rtrimArrayValues($arr);
  328.         }
  329.         if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
  330.             $this->_convertNullArrayValuesToEmpty($arr);
  331.         }
  332.         return DB_OK;
  333.     }
  334.  
  335.     // }}}
  336.     // {{{ freeResult()
  337.  
  338.     /**
  339.      * Deletes the result set and frees the memory occupied by the result set
  340.      *
  341.      * This method is not meant to be called directly.  Use
  342.      * DB_result::free() instead.  It can't be declared "protected"
  343.      * because DB_result is a separate object.
  344.      *
  345.      * @param resource $result  PHP's query result resource
  346.      *
  347.      * @return bool  TRUE on success, FALSE if $result is invalid
  348.      *
  349.      * @see DB_result::free()
  350.      */
  351.     function freeResult($result)
  352.     {
  353.         return @msql_free_result($result);
  354.     }
  355.  
  356.     // }}}
  357.     // {{{ numCols()
  358.  
  359.     /**
  360.      * Gets the number of columns in a result set
  361.      *
  362.      * This method is not meant to be called directly.  Use
  363.      * DB_result::numCols() instead.  It can't be declared "protected"
  364.      * because DB_result is a separate object.
  365.      *
  366.      * @param resource $result  PHP's query result resource
  367.      *
  368.      * @return int  the number of columns.  A DB_Error object on failure.
  369.      *
  370.      * @see DB_result::numCols()
  371.      */
  372.     function numCols($result)
  373.     {
  374.         $cols = @msql_num_fields($result);
  375.         if (!$cols) {
  376.             return $this->msqlRaiseError();
  377.         }
  378.         return $cols;
  379.     }
  380.  
  381.     // }}}
  382.     // {{{ numRows()
  383.  
  384.     /**
  385.      * Gets the number of rows in a result set
  386.      *
  387.      * This method is not meant to be called directly.  Use
  388.      * DB_result::numRows() instead.  It can't be declared "protected"
  389.      * because DB_result is a separate object.
  390.      *
  391.      * @param resource $result  PHP's query result resource
  392.      *
  393.      * @return int  the number of rows.  A DB_Error object on failure.
  394.      *
  395.      * @see DB_result::numRows()
  396.      */
  397.     function numRows($result)
  398.     {
  399.         $rows = @msql_num_rows($result);
  400.         if ($rows === false) {
  401.             return $this->msqlRaiseError();
  402.         }
  403.         return $rows;
  404.     }
  405.  
  406.     // }}}
  407.     // {{{ affected()
  408.  
  409.     /**
  410.      * Determines the number of rows affected by a data maniuplation query
  411.      *
  412.      * 0 is returned for queries that don't manipulate data.
  413.      *
  414.      * @return int  the number of rows.  A DB_Error object on failure.
  415.      */
  416.     function affectedRows()
  417.     {
  418.         if (!$this->_result) {
  419.             return 0;
  420.         }
  421.         return msql_affected_rows($this->_result);
  422.     }
  423.  
  424.     // }}}
  425.     // {{{ nextId()
  426.  
  427.     /**
  428.      * Returns the next free id in a sequence
  429.      *
  430.      * @param string  $seq_name  name of the sequence
  431.      * @param boolean $ondemand  when true, the seqence is automatically
  432.      *                            created if it does not exist
  433.      *
  434.      * @return int  the next id number in the sequence.
  435.      *               A DB_Error object on failure.
  436.      *
  437.      * @see DB_common::nextID(), DB_common::getSequenceName(),
  438.      *      DB_msql::createSequence(), DB_msql::dropSequence()
  439.      */
  440.     function nextId($seq_name, $ondemand = true)
  441.     {
  442.         $seqname = $this->getSequenceName($seq_name);
  443.         $repeat = false;
  444.         do {
  445.             $this->pushErrorHandling(PEAR_ERROR_RETURN);
  446.             $result =& $this->query("SELECT _seq FROM ${seqname}");
  447.             $this->popErrorHandling();
  448.             if ($ondemand && DB::isError($result) &&
  449.                 $result->getCode() == DB_ERROR_NOSUCHTABLE) {
  450.                 $repeat = true;
  451.                 $this->pushErrorHandling(PEAR_ERROR_RETURN);
  452.                 $result = $this->createSequence($seq_name);
  453.                 $this->popErrorHandling();
  454.                 if (DB::isError($result)) {
  455.                     return $this->raiseError($result);
  456.                 }
  457.             } else {
  458.                 $repeat = false;
  459.             }
  460.         } while ($repeat);
  461.         if (DB::isError($result)) {
  462.             return $this->raiseError($result);
  463.         }
  464.         $arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
  465.         $result->free();
  466.         return $arr[0];
  467.     }
  468.  
  469.     // }}}
  470.     // {{{ createSequence()
  471.  
  472.     /**
  473.      * Creates a new sequence
  474.      *
  475.      * Also creates a new table to associate the sequence with.  Uses
  476.      * a separate table to ensure portability with other drivers.
  477.      *
  478.      * @param string $seq_name  name of the new sequence
  479.      *
  480.      * @return int  DB_OK on success.  A DB_Error object on failure.
  481.      *
  482.      * @see DB_common::createSequence(), DB_common::getSequenceName(),
  483.      *      DB_msql::nextID(), DB_msql::dropSequence()
  484.      */
  485.     function createSequence($seq_name)
  486.     {
  487.         $seqname = $this->getSequenceName($seq_name);
  488.         $res = $this->query('CREATE TABLE ' . $seqname
  489.                             . ' (id INTEGER NOT NULL)');
  490.         if (DB::isError($res)) {
  491.             return $res;
  492.         }
  493.         $res = $this->query("CREATE SEQUENCE ON ${seqname}");
  494.         return $res;
  495.     }
  496.  
  497.     // }}}
  498.     // {{{ dropSequence()
  499.  
  500.     /**
  501.      * Deletes a sequence
  502.      *
  503.      * @param string $seq_name  name of the sequence to be deleted
  504.      *
  505.      * @return int  DB_OK on success.  A DB_Error object on failure.
  506.      *
  507.      * @see DB_common::dropSequence(), DB_common::getSequenceName(),
  508.      *      DB_msql::nextID(), DB_msql::createSequence()
  509.      */
  510.     function dropSequence($seq_name)
  511.     {
  512.         return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
  513.     }
  514.  
  515.     // }}}
  516.     // {{{ quoteIdentifier()
  517.  
  518.     /**
  519.      * mSQL does not support delimited identifiers
  520.      *
  521.      * @param string $str  the identifier name to be quoted
  522.      *
  523.      * @return object  a DB_Error object
  524.      *
  525.      * @see DB_common::quoteIdentifier()
  526.      * @since Method available since Release 1.7.0
  527.      */
  528.     function quoteIdentifier($str)
  529.     {
  530.         return $this->raiseError(DB_ERROR_UNSUPPORTED);
  531.     }
  532.  
  533.     // }}}
  534.     // {{{ escapeSimple()
  535.  
  536.     /**
  537.      * Escapes a string according to the current DBMS's standards
  538.      *
  539.      * @param string $str  the string to be escaped
  540.      *
  541.      * @return string  the escaped string
  542.      *
  543.      * @see DB_common::quoteSmart()
  544.      * @since Method available since Release 1.7.0
  545.      */
  546.     function escapeSimple($str)
  547.     {
  548.         return addslashes($str);
  549.     }
  550.  
  551.     // }}}
  552.     // {{{ msqlRaiseError()
  553.  
  554.     /**
  555.      * Produces a DB_Error object regarding the current problem
  556.      *
  557.      * @param int $errno  if the error is being manually raised pass a
  558.      *                     DB_ERROR* constant here.  If this isn't passed
  559.      *                     the error information gathered from the DBMS.
  560.      *
  561.      * @return object  the DB_Error object
  562.      *
  563.      * @see DB_common::raiseError(),
  564.      *      DB_msql::errorNative(), DB_msql::errorCode()
  565.      */
  566.     function msqlRaiseError($errno = null)
  567.     {
  568.         $native = $this->errorNative();
  569.         if ($errno === null) {
  570.             $errno = $this->errorCode($native);
  571.         }
  572.         return $this->raiseError($errno, null, null, null, $native);
  573.     }
  574.  
  575.     // }}}
  576.     // {{{ errorNative()
  577.  
  578.     /**
  579.      * Gets the DBMS' native error message produced by the last query
  580.      *
  581.      * @return string  the DBMS' error message
  582.      */
  583.     function errorNative()
  584.     {
  585.         return @msql_error();
  586.     }
  587.  
  588.     // }}}
  589.     // {{{ errorCode()
  590.  
  591.     /**
  592.      * Determines PEAR::DB error code from the database's text error message
  593.      *
  594.      * @param string $errormsg  the error message returned from the database
  595.      *
  596.      * @return integer  the error number from a DB_ERROR* constant
  597.      */
  598.     function errorCode($errormsg)
  599.     {
  600.         static $error_regexps;
  601.         if (!isset($error_regexps)) {
  602.             $error_regexps = array(
  603.                 '/^Access to database denied/i'
  604.                     => DB_ERROR_ACCESS_VIOLATION,
  605.                 '/^Bad index name/i'
  606.                     => DB_ERROR_ALREADY_EXISTS,
  607.                 '/^Bad order field/i'
  608.                     => DB_ERROR_SYNTAX,
  609.                 '/^Bad type for comparison/i'
  610.                     => DB_ERROR_SYNTAX,
  611.                 '/^Can\'t perform LIKE on/i'
  612.                     => DB_ERROR_SYNTAX,
  613.                 '/^Can\'t use TEXT fields in LIKE comparison/i'
  614.                     => DB_ERROR_SYNTAX,
  615.                 '/^Couldn\'t create temporary table/i'
  616.                     => DB_ERROR_CANNOT_CREATE,
  617.                 '/^Error creating table file/i'
  618.                     => DB_ERROR_CANNOT_CREATE,
  619.                 '/^Field .* cannot be null$/i'
  620.                     => DB_ERROR_CONSTRAINT_NOT_NULL,
  621.                 '/^Index (field|condition) .* cannot be null$/i'
  622.                     => DB_ERROR_SYNTAX,
  623.                 '/^Invalid date format/i'
  624.                     => DB_ERROR_INVALID_DATE,
  625.                 '/^Invalid time format/i'
  626.                     => DB_ERROR_INVALID,
  627.                 '/^Literal value for .* is wrong type$/i'
  628.                     => DB_ERROR_INVALID_NUMBER,
  629.                 '/^No Database Selected/i'
  630.                     => DB_ERROR_NODBSELECTED,
  631.                 '/^No value specified for field/i'
  632.                     => DB_ERROR_VALUE_COUNT_ON_ROW,
  633.                 '/^Non unique value for unique index/i'
  634.                     => DB_ERROR_CONSTRAINT,
  635.                 '/^Out of memory for temporary table/i'
  636.                     => DB_ERROR_CANNOT_CREATE,
  637.                 '/^Permission denied/i'
  638.                     => DB_ERROR_ACCESS_VIOLATION,
  639.                 '/^Reference to un-selected table/i'
  640.                     => DB_ERROR_SYNTAX,
  641.                 '/^syntax error/i'
  642.                     => DB_ERROR_SYNTAX,
  643.                 '/^Table .* exists$/i'
  644.                     => DB_ERROR_ALREADY_EXISTS,
  645.                 '/^Unknown database/i'
  646.                     => DB_ERROR_NOSUCHDB,
  647.                 '/^Unknown field/i'
  648.                     => DB_ERROR_NOSUCHFIELD,
  649.                 '/^Unknown (index|system variable)/i'
  650.                     => DB_ERROR_NOT_FOUND,
  651.                 '/^Unknown table/i'
  652.                     => DB_ERROR_NOSUCHTABLE,
  653.                 '/^Unqualified field/i'
  654.                     => DB_ERROR_SYNTAX,
  655.             );
  656.         }
  657.  
  658.         foreach ($error_regexps as $regexp => $code) {
  659.             if (preg_match($regexp, $errormsg)) {
  660.                 return $code;
  661.             }
  662.         }
  663.         return DB_ERROR;
  664.     }
  665.  
  666.     // }}}
  667.     // {{{ tableInfo()
  668.  
  669.     /**
  670.      * Returns information about a table or a result set
  671.      *
  672.      * @param object|string  $result  DB_result object from a query or a
  673.      *                                 string containing the name of a table.
  674.      *                                 While this also accepts a query result
  675.      *                                 resource identifier, this behavior is
  676.      *                                 deprecated.
  677.      * @param int            $mode    a valid tableInfo mode
  678.      *
  679.      * @return array  an associative array with the information requested.
  680.      *                 A DB_Error object on failure.
  681.      *
  682.      * @see DB_common::setOption()
  683.      */
  684.     function tableInfo($result, $mode = null)
  685.     {
  686.         if (is_string($result)) {
  687.             /*
  688.              * Probably received a table name.
  689.              * Create a result resource identifier.
  690.              */
  691.             $id = @msql_query("SELECT * FROM $result",
  692.                               $this->connection);
  693.             $got_string = true;
  694.         } elseif (isset($result->result)) {
  695.             /*
  696.              * Probably received a result object.
  697.              * Extract the result resource identifier.
  698.              */
  699.             $id = $result->result;
  700.             $got_string = false;
  701.         } else {
  702.             /*
  703.              * Probably received a result resource identifier.
  704.              * Copy it.
  705.              * Deprecated.  Here for compatibility only.
  706.              */
  707.             $id = $result;
  708.             $got_string = false;
  709.         }
  710.  
  711.         if (!is_resource($id)) {
  712.             return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
  713.         }
  714.  
  715.         if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
  716.             $case_func = 'strtolower';
  717.         } else {
  718.             $case_func = 'strval';
  719.         }
  720.  
  721.         $count = @msql_num_fields($id);
  722.         $res   = array();
  723.  
  724.         if ($mode) {
  725.             $res['num_fields'] = $count;
  726.         }
  727.  
  728.         for ($i = 0; $i < $count; $i++) {
  729.             $tmp = @msql_fetch_field($id);
  730.  
  731.             $flags = '';
  732.             if ($tmp->not_null) {
  733.                 $flags .= 'not_null ';
  734.             }
  735.             if ($tmp->unique) {
  736.                 $flags .= 'unique_key ';
  737.             }
  738.             $flags = trim($flags);
  739.  
  740.             $res[$i] = array(
  741.                 'table' => $case_func($tmp->table),
  742.                 'name'  => $case_func($tmp->name),
  743.                 'type'  => $tmp->type,
  744.                 'len'   => msql_field_len($id, $i),
  745.                 'flags' => $flags,
  746.             );
  747.  
  748.             if ($mode & DB_TABLEINFO_ORDER) {
  749.                 $res['order'][$res[$i]['name']] = $i;
  750.             }
  751.             if ($mode & DB_TABLEINFO_ORDERTABLE) {
  752.                 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
  753.             }
  754.         }
  755.  
  756.         // free the result only if we were called on a table
  757.         if ($got_string) {
  758.             @msql_free_result($id);
  759.         }
  760.         return $res;
  761.     }
  762.  
  763.     // }}}
  764.     // {{{ getSpecialQuery()
  765.  
  766.     /**
  767.      * Obtain a list of a given type of objects
  768.      *
  769.      * @param string $type  the kind of objects you want to retrieve
  770.      *
  771.      * @return array  the array containing the list of objects requested
  772.      *
  773.      * @access protected
  774.      * @see DB_common::getListOf()
  775.      */
  776.     function getSpecialQuery($type)
  777.     {
  778.         switch ($type) {
  779.             case 'databases':
  780.                 $id = @msql_list_dbs($this->connection);
  781.                 break;
  782.             case 'tables':
  783.                 $id = @msql_list_tables($this->dsn['database'],
  784.                                         $this->connection);
  785.                 break;
  786.             default:
  787.                 return null;
  788.         }
  789.         if (!$id) {
  790.             return $this->msqlRaiseError();
  791.         }
  792.         $out = array();
  793.         while ($row = @msql_fetch_row($id)) {
  794.             $out[] = $row[0];
  795.         }
  796.         return $out;
  797.     }
  798.  
  799.     // }}}
  800.  
  801. }
  802.  
  803. /*
  804.  * Local variables:
  805.  * tab-width: 4
  806.  * c-basic-offset: 4
  807.  * End:
  808.  */
  809.  
  810. ?>
  811.